/*
 * CommunicationRobot5.cpp
 *
 *  
 */

#include "CommunicationRobot5.h"

namespace middleware {

const std::string CommunicationRobot5::R5_SEM_PATH = "/tmp/robot5sem";
const std::string CommunicationRobot5::R5_SHMEM_PATH = "/tmp/robot5shmem";
const std::string CommunicationRobot5::R5_QUEUE_PATH = "/tmp/robot5queue";

CommunicationRobot5::CommunicationRobot5() :
							colaCanastos(ipc::MessageQueue<PedidoCanasto>::get(R5_QUEUE_PATH, R5_QUEUE_CANASTOS_KEY)),
							colaCintas(ipc::MessageQueue<PedidoCintas>::get(R5_QUEUE_PATH, R5_QUEUE_CINTAS_KEY)),
							colaProduccion(ipc::MessageQueue<PedidoProduccion>::get(R5_QUEUE_PATH, R5_QUEUE_PRODUCCION_KEY)),
							colaGabinetes(ipc::MessageQueue<PedidoGabinetes>::get(R5_QUEUE_PATH, R5_QUEUE_GABINETES_KEY)),
							colaIntercambio(ipc::MessageQueue<Canasto>::get(R5_QUEUE_PATH, R5_AGV_QUEUE_INTERCAMBIO_KEY)),
							colaRecpcionCanastos(ipc::MessageQueue<Canasto>::get(R5_QUEUE_PATH, R5_ADP_QUEUE_INTERCAMBIO_KEY)),
							colaEnvioPedidosAlADP(ipc::MessageQueue<PedidoCanasto>::get(R5_QUEUE_PATH, R5_ADP_QUEUE_PEDIDOS_KEY)),
							shMemPendientes(ipc::SharedMemoryInterface<PendientesRobot5>::get(R5_SHMEM_PATH, R5_SHMEM_PENDIENTES_KEY)),
							shMemEstado(ipc::SharedMemoryInterface<EstadoRobot5>::get(R5_SHMEM_PATH, R5_SHMEM_ESTADO_KEY)),
							semBloqueo(ipc::Semaphore::get(R5_SEM_PATH, R5_SEM_KEY))
{
	this->semBloqueo.initialize(0);
}


void CommunicationRobot5::pedirCanastoAR5(PedidoCanasto pedido){
	colaCanastos.put(R5_TIPO_PEDIDO_CANASTO, pedido);
}

PendientesRobot5 CommunicationRobot5::getListaPedidos(){
	shMemPendientes.lock();
	PendientesRobot5 pendientes = shMemPendientes.read(0);
	return pendientes;
}

void CommunicationRobot5::setListaPedidos(PendientesRobot5 pendientes){
	shMemPendientes.write(pendientes);
	shMemPendientes.unlock();
}

EstadoRobot5 CommunicationRobot5::verEstado(){
	shMemEstado.lock();
	return shMemEstado.read();
}

void CommunicationRobot5::liberarPendientes(){
	shMemPendientes.unlock();
	return;
}

void CommunicationRobot5::despertar(){
	shMemEstado.write(R5_ESTADO_ACTIVO);
	semBloqueo.signal();
}

void CommunicationRobot5::dormir(){
	semBloqueo.wait();
}

void CommunicationRobot5::despertarInteligente(){
	shMemEstado.lock();
	EstadoRobot5 estado = shMemEstado.read();
	if (estado == R5_ESTADO_DURMIENDO) {
		estado = R5_ESTADO_ACTIVO;
		shMemEstado.write(estado);
		semBloqueo.signal();
	}
	shMemEstado.unlock();
}

void CommunicationRobot5::incrementarPedidos(int index){
	PendientesRobot5 pendientes = this->getListaPedidos();
	pendientes.contador[index]++;
	this->setListaPedidos(pendientes);
}

void CommunicationRobot5::decrementarPedidos(int index){
	PendientesRobot5 pendientes = this->getListaPedidos();
	pendientes.contador[index]--;
	this->setListaPedidos(pendientes);
}

void CommunicationRobot5::enviarAvisoDeCintaAR5(PedidoCintas pedido){
	colaCintas.put(R5_TIPO_CINTAS, pedido);
}


Canasto CommunicationRobot5::getCanastoDeADP(){
	return colaRecpcionCanastos.get(R5_TIPO_RECEPCION_CANASTO);
}

void CommunicationRobot5::pedirCanastoAlADP(Canasto c){
	//FIXME Mock
	colaRecpcionCanastos.put(R5_TIPO_RECEPCION_CANASTO, c);
}

void CommunicationRobot5::llevarCanastoAlAGV(int idAGV,Canasto canasto){
	//segun el id del agv se manda con ese id por la cola
	colaIntercambio.put(idAGV,canasto);
}

Canasto CommunicationRobot5::recibirCanastoDel5(int idAGV){
	return colaIntercambio.get(idAGV);
}

PedidoCanasto CommunicationRobot5::getPedidoDeCanasto(){
	return colaCanastos.get(R5_TIPO_PEDIDO_CANASTO);
}

PedidoCintas CommunicationRobot5::getPedidoDeCinta(){
	return colaCintas.get(R5_TIPO_CINTAS);
}

PedidoProduccion CommunicationRobot5::getPedidoDeProd(){
	return colaProduccion.get(R5_TIPO_PRODUCCION);
}

void CommunicationRobot5::noHacerNada(){
	shMemEstado.lock();
	shMemEstado.write(R5_ESTADO_DURMIENDO);
	shMemEstado.unlock();
	shMemPendientes.unlock();
	semBloqueo.wait();
}

void CommunicationRobot5::create(){
	ipc::MessageQueue<PedidoCanasto>::create(R5_QUEUE_PATH, R5_QUEUE_CANASTOS_KEY);
	ipc::MessageQueue<PedidoCintas>::create(R5_QUEUE_PATH, R5_QUEUE_CINTAS_KEY);
	ipc::MessageQueue<PedidoProduccion>::create(R5_QUEUE_PATH, R5_QUEUE_PRODUCCION_KEY);
	ipc::MessageQueue<PedidoGabinetes>::create(R5_QUEUE_PATH, R5_QUEUE_GABINETES_KEY);
	ipc::MessageQueue<Canasto>::create(R5_QUEUE_PATH, R5_AGV_QUEUE_INTERCAMBIO_KEY);
	ipc::MessageQueue<Canasto>::create(R5_QUEUE_PATH, R5_ADP_QUEUE_INTERCAMBIO_KEY);
	ipc::MessageQueue<PedidoCanasto>::create(R5_QUEUE_PATH, R5_ADP_QUEUE_PEDIDOS_KEY);
	ipc::SharedMemoryInterface<PendientesRobot5>::create(R5_SHMEM_PATH, R5_SHMEM_PENDIENTES_KEY);
	ipc::SharedMemoryInterface<EstadoRobot5>::create(R5_SHMEM_PATH, R5_SHMEM_ESTADO_KEY);
	ipc::Semaphore::create(R5_SEM_PATH, R5_SEM_KEY);
}

void CommunicationRobot5::destroy(){
	ipc::MessageQueue<PedidoCanasto>::destroy(R5_QUEUE_PATH, R5_QUEUE_CANASTOS_KEY);
	ipc::MessageQueue<PedidoCintas>::destroy(R5_QUEUE_PATH, R5_QUEUE_CINTAS_KEY);
	ipc::MessageQueue<PedidoProduccion>::destroy(R5_QUEUE_PATH, R5_QUEUE_PRODUCCION_KEY);
	ipc::MessageQueue<PedidoGabinetes>::destroy(R5_QUEUE_PATH, R5_QUEUE_GABINETES_KEY);
	ipc::MessageQueue<Canasto>::destroy(R5_QUEUE_PATH, R5_AGV_QUEUE_INTERCAMBIO_KEY);
	ipc::MessageQueue<Canasto>::destroy(R5_QUEUE_PATH, R5_ADP_QUEUE_INTERCAMBIO_KEY);
	ipc::MessageQueue<PedidoCanasto>::destroy(R5_QUEUE_PATH, R5_ADP_QUEUE_PEDIDOS_KEY);
	ipc::SharedMemoryInterface<PendientesRobot5>::destroy(R5_SHMEM_PATH, R5_SHMEM_PENDIENTES_KEY);
	ipc::SharedMemoryInterface<EstadoRobot5>::destroy(R5_SHMEM_PATH, R5_SHMEM_ESTADO_KEY);
	ipc::Semaphore::destroy(R5_SEM_PATH, R5_SEM_KEY);
}

void CommunicationRobot5::enviarAProducir(PedidoProduccion pedido) {
	this->colaProduccion.put(R5_TIPO_PRODUCCION, pedido);
}

CommunicationRobot5::~CommunicationRobot5() {
}

} /* namespace middleware */
